﻿# ------------------------------- #
# SharePoint Server Configuration #
# ------------------------------- #
param([string]$virtualMachineService, [string]$virtualMachineName)

Write-Information "Virtual machine '$virtualMachineName' SharePoint Server '$($script.type)' configuration ... " -NoNewLine $true
$userName = $subscription.virtualMachines.adminUserName
$password = $subscription.virtualMachines.password
$netBiosDomain = $subscription.virtualMachines.netBiosDomain
$uri = Get-AzureWinRMUri -ServiceName $virtualMachineService -Name $virtualMachineName
$credential = New-Object System.Management.Automation.PSCredential(($netBiosDomain + "\" + $userName), (ConvertTo-SecureString $password -AsPlainText -Force))
$session = New-PSSession -ComputerName $uri[0].DnsSafeHost -Credential $credential -Port (Get-VirtualMachineInstanceEndpointPort $subscription $virtualMachineName) -UseSSL -Authentication Credssp
switch ($script.type)
{
	"Prepare"
	{
		Invoke-Command -Session $session -ScriptBlock {
			Import-Module ServerManager
			$result = Add-WindowsFeature NET-WCF-HTTP-Activation45,NET-WCF-TCP-Activation45,NET-WCF-Pipe-Activation45 -Source W:\sources\sxs -WarningAction Ignore
			if (!$? -or $result.Success -eq $false) {throw ".NET Framework 3.5 deployment failed."}
			$result = Add-WindowsFeature Net-Framework-Features,Web-Server,Web-WebServer,Web-Common-Http,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-App-Dev,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Health,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor,Web-Http-Tracing,Web-Security,Web-Basic-Auth,Web-Windows-Auth,Web-Filtering,Web-Digest-Auth,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression,Web-Mgmt-Tools,Web-Mgmt-Console,Web-Mgmt-Compat,Web-Metabase,Application-Server,AS-Web-Support,AS-TCP-Port-Sharing,AS-WAS-Support, AS-HTTP-Activation,AS-TCP-Activation,AS-Named-Pipes,AS-Net-Framework,WAS,WAS-Process-Model,WAS-NET-Environment,WAS-Config-APIs,Web-Lgcy-Scripting,Windows-Identity-Foundation,Server-Media-Foundation,Xps-Viewer -Source W:\sources\sxs -WarningAction Ignore
			if (!$? -or $result.Success -eq $false) {throw "Web Server deployment failed."}
	        # Disable user access control (required to provision User Profile Service Application)
            if ((Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -ErrorAction SilentlyContinue).EnableLUA -ne "0")
            {
	            $item = Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 0
            }
		}
        Remove-PSSession $session
        Write-Text "done."
        Restart-VirtualMachineInstance $subscription $virtualMachineService $virtualMachineName $true
        return
	}
	"Prerequisites"
	{
		Send-RemoteFile -Source "$env:dp0\Files\$($script.configuration)" -Destination "C:\SPS_2013.xml" -Session $session
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$productKey, [string]$password)
            $content = Get-Content -LiteralPath 'C:\SPS_2013.xml' | Out-String
            $content = $content.Replace("[PIDKey]", $productKey)
            $content = $content.Replace("[Password]", $password)
            $content | Out-File -LiteralPath 'C:\SPS_2013.xml'
			Start-Process -FilePath "$PSHOME\powershell.exe" -Verb RunAs -ArgumentList "-ExecutionPolicy Bypass -File S:\SP\AutoSPInstaller\AutoSPInstallerMain.ps1 -InputFile C:\SPS_2013.xml" -Wait
		} -ArgumentList $script.productKey, $script.password
        Remove-PSSession $session
        Write-Text "done."
        Restart-VirtualMachineInstance $subscription $virtualMachineService $virtualMachineName $false
        return
	}
	"Install"
	{
		Invoke-Command -Session $session -ScriptBlock {
			Start-Process -FilePath "$PSHOME\powershell.exe" -Verb RunAs -ArgumentList "-ExecutionPolicy Bypass -File S:\SP\AutoSPInstaller\AutoSPInstallerMain.ps1 -InputFile C:\SPS_2013.xml" -Wait
			Remove-Item "C:\SPS_2013.xml" -Force
		}
	}
	"Register ADFS"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$issuingServer, [string]$rootCertificateFile, [string]$issuingCertificateFile, [string]$trustCertificateFile, [string]$realm, [string]$additionalRealms, [string]$signinUrl)
            Add-PSSnapin Microsoft.SharePoint.PowerShell
            # Configure SharePoint Trusted Root Authority (Central Admin: Security -> Manage Trust, Get-SPTrustedRootAuthority)
            if ((Get-SPTrustedRootAuthority | ? {$_.Name -eq $rootCertificateFile}) -ne $null) { Remove-SPTrustedRootAuthority $rootCertificateFile -Confirm:$false }
            New-SPTrustedRootAuthority -Name $rootCertificateFile -Certificate (New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("\\$issuingServer\C$\Certificates\$rootCertificateFile.crt")) | Out-Null
            if ((Get-SPTrustedRootAuthority | ? {$_.Name -eq $issuingCertificateFile}) -ne $null) { Remove-SPTrustedRootAuthority $issuingCertificateFile -Confirm:$false }
            New-SPTrustedRootAuthority -Name $issuingCertificateFile -Certificate (New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("\\$issuingServer\C$\Certificates\$issuingCertificateFile.crt")) | Out-Null
            # Configure SharePoint Trusted Identity Token Issuer (Get-SPTrustedIdentityTokenIssuer)
            $emailAddressMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
            $upnMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "UPN" -SameAsIncoming
            $roleMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" -IncomingClaimTypeDisplayName "Role" -SameAsIncoming
            $loginMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname" -IncomingClaimTypeDisplayName "Login" -SameAsIncoming
            $sidMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid" -IncomingClaimTypeDisplayName "SID" -SameAsIncoming
            $displayNameMapping = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/CommonName" -IncomingClaimTypeDisplayName "Display Name" -SameAsIncoming
            if ((Get-SPTrustedIdentityTokenIssuer | ? { $_.Name -eq "ADFS Provider"}) -ne $null) { Get-SPTrustedIdentityTokenIssuer | ? { $_.Name -eq "ADFS Provider"} | Remove-SPTrustedIdentityTokenIssuer -Confirm:$false }
            $issuer = New-SPTrustedIdentityTokenIssuer -Name "ADFS Provider" -Description "ADFS Trusted Identity Provider" `
                -IdentifierClaim $emailAddressMapping.InputClaimType -ClaimsMappings $emailAddressMapping, $upnMapping, $roleMapping, $loginMapping, $sidMapping, $displayNameMapping `
                -Realm $realm -SignInUrl $signinUrl `
                -ImportTrustCertificate (New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("\\$issuingServer\C$\Certificates\$trustCertificateFile.crt"))
            foreach ($additionalRealm in $additionalRealms.Split(";"))
            {
                $uri = New-Object System.Uri($additionalRealm.Split(",")[0])
                $issuer.ProviderRealms.Add($uri, $additionalRealm.Split(",")[1])
            }
            $issuer.Update()
		} -ArgumentList $script.issuingServer, $script.rootCertificateFile, $script.issuingCertificateFile, $script.trustCertificateFile, $script.realm, $script.additionalRealms, $script.signinUrl
	}
	"Enable ADFS"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$webApplication, [string]$claimValue, [string]$claimType)
            Add-PSSnapin Microsoft.SharePoint.PowerShell
            # Enable ADFS Provider
            $provider1 = New-SPAuthenticationProvider -UseWindowsIntegratedAuthentication
            $provider2 = New-SPAuthenticationProvider -TrustedIdentityTokenIssuer "ADFS Provider"
            Set-SPWebApplication $webApplication -Zone "Default" -AuthenticationProvider $provider1, $provider2
            # Grant claims user Full Control
            $webApp = Get-SPWebApplication $webApplication
            $claim = New-SPClaimsPrincipal -ClaimValue $claimValue -ClaimType $claimType -TrustedIdentityTokenIssuer "ADFS Provider"
            $policy = $webApp.Policies.Add($claim.ToEncodedString(), $claimValue)
            $policyRole = $webApp.PolicyRoles | ? {$_.Name -eq "Full Control"}
            $policy.PolicyRoleBindings.Add($policyRole)
            $webApp.Update()
		} -ArgumentList $script.webApplication, $script.adminClaimValue, $script.adminClaimType
	}
	default
	{
		throw "SharePoint Server type '$($script.type)' is not supported."
	}
}
Remove-PSSession $session
Write-Text "done."